"""Adds new Slack command for read-in summary generation

Revision ID: aa87efd3d6c1
Revises: f63ad392dbbf
Create Date: 2025-07-11 10:02:39.819258

"""

from alembic import op
from pydantic import SecretStr, ValidationError
from pydantic.json import pydantic_encoder

from sqlalchemy import Column, Integer, ForeignKey, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, Session
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy_utils import StringEncryptedType
from sqlalchemy_utils.types.encrypted.encrypted_type import AesEngine
from dispatch.config import config, DISPATCH_ENCRYPTION_KEY


# revision identifiers, used by Alembic.
revision = "aa87efd3d6c1"
down_revision = "f63ad392dbbf"
branch_labels = None
depends_on = None

Base = declarative_base()


def show_secrets_encoder(obj):
    if isinstance(obj, SecretStr):
        return obj.get_secret_value()
    else:
        return pydantic_encoder(obj)


def migrate_config(instances, slug, config):
    for instance in instances:
        if slug == instance.plugin.slug:
            instance.configuration = config


class Plugin(Base):
    __tablename__ = "plugin"
    __table_args__ = {"schema": "dispatch_core"}
    id = Column(Integer, primary_key=True)
    slug = Column(String, unique=True)


class PluginInstance(Base):
    __tablename__ = "plugin_instance"
    id = Column(Integer, primary_key=True)
    _configuration = Column(
        StringEncryptedType(key=str(DISPATCH_ENCRYPTION_KEY), engine=AesEngine, padding="pkcs5")
    )
    plugin_id = Column(Integer, ForeignKey(Plugin.id))
    plugin = relationship(Plugin, backref="instances")

    @hybrid_property
    def configuration(self):
        """Property that correctly returns a plugins configuration object."""
        pass

    @configuration.setter
    def configuration(self, configuration):
        """Property that correctly sets a plugins configuration object."""
        if configuration:
            self._configuration = configuration.json(encoder=show_secrets_encoder)


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    from dispatch.plugins.dispatch_slack.config import SlackConversationConfiguration

    bind = op.get_bind()
    session = Session(bind=bind)

    instances = session.query(PluginInstance).all()

    # Slash commands
    SLACK_COMMAND_SUMMARY_SLUG = config("SLACK_COMMAND_SUMMARY_SLUG", default="/dispatch-summary")

    try:
        slack_conversation_config = SlackConversationConfiguration(
            slack_command_summary=SLACK_COMMAND_SUMMARY_SLUG,
        )

        migrate_config(instances, "slack-conversation", slack_conversation_config)

    except ValidationError:
        print(
            "Skipping automatic migration of slack plugin credentials, if you are using the slack plugin manually migrate credentials."
        )

    session.commit()
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    pass
    # ### end Alembic commands ###
